home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 3 / CD ACTUAL 3.iso / linux / incoming / libgr-2.000 / libgr-2 / libgr-2.0.3 / rle / rle_getraw.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-08-14  |  7.5 KB  |  291 lines

  1. /*
  2.  * This software is copyrighted as noted below.  It may be freely copied,
  3.  * modified, and redistributed, provided that the copyright notice is 
  4.  * preserved on all copies.
  5.  * 
  6.  * There is no warranty or other guarantee of fitness for this software,
  7.  * it is provided solely "as is".  Bug reports or fixes may be sent
  8.  * to the author, who may or may not act on them as he desires.
  9.  *
  10.  * You may not include this software in a program or other software product
  11.  * without supplying the source, or without informing the end-user that the 
  12.  * source is available for no extra charge.
  13.  *
  14.  * If you modify this software, you should include a notice giving the
  15.  * name of the person performing the modification, the date of modification,
  16.  * and the reason for such modification.
  17.  *
  18.  *  Modified at BRL 16-May-88 by Mike Muuss to avoid Alliant STDC desire
  19.  *  to have all "void" functions so declared.
  20.  */
  21. /* 
  22.  * rle_getraw.c - 
  23.  * 
  24.  * Author:    Spencer W. Thomas
  25.  *         Computer Science Dept.
  26.  *         University of Utah
  27.  * Date:    Mon Nov 10 1986
  28.  * Copyright (c) 1986, University of Utah
  29.  */
  30. #ifndef lint
  31. static char rcs_ident[] = "rle_getraw.c,v 1.1.1.1 1995/08/15 02:46:22 neal Exp";
  32. #endif
  33.  
  34. #include <stdio.h>
  35. #include "rle.h"
  36. #include "rle_raw.h"
  37.  
  38. /* Read a two-byte "short" that started in VAX (LITTLE_ENDIAN) order */
  39. #define VAXSHORT( var, fp )\
  40.     { var = fgetc(fp)&0xFF; var |= (fgetc(fp)) << 8; }
  41.   
  42. /* Instruction format -- first byte is opcode, second is datum. */
  43.  
  44. #define OPCODE(inst) (inst[0] & ~LONG)
  45. #define LONGP(inst) (inst[0] & LONG)
  46. #define DATUM(inst) (inst[1] & 0xff)    /* Make sure it's unsigned. */
  47.  
  48. /*****************************************************************
  49.  * TAG( rle_getraw )
  50.  * 
  51.  * Get a raw scanline from the input file.
  52.  * Inputs:
  53.  *    the_hdr:    rle_hdr structure containing information about 
  54.  *            the input file.
  55.  * Outputs:
  56.  *     scanraw:    an array of pointers to the individual color
  57.  *            scanlines.  Scanraw is assumed to have
  58.  *            the_hdr->ncolors pointers to arrays of rle_op,
  59.  *            each of which with enough elements, at least
  60.  *            1 + (the_hdr->xmax - the_hdr->xmin) / 3.
  61.  *    nraw:        an array of integers giving the number of rle_ops for
  62.  *            each color channel.
  63.  *    Returns the current scanline number.  Returns 32768 at EOF.
  64.  * Assumptions:
  65.  *     rle_get_setup has already been called.
  66.  * Algorithm:
  67.  *    Read input until a vertical skip is encountered,
  68.  *    decoding the instructions into the scanraw array.
  69.  *    Vertical skips that separate scanlines with no data do not
  70.  *    cause a return.  In other words, the only reason for returning
  71.  *    with an empty scanline is end of file.
  72.  *
  73.  *    When the scan_y reaches or exceeds the ymax, the rest of the
  74.  *    input image is skipped.  This avoids problems with malformed
  75.  *    input files.
  76.  */
  77. unsigned int
  78. rle_getraw( the_hdr, scanraw, nraw )
  79. rle_hdr *the_hdr;
  80. rle_op *scanraw[];
  81. int nraw[];
  82. {
  83.     register int channel;
  84.     register rle_op * rawp = NULL;
  85.     FILE *infile = the_hdr->rle_file;
  86.     char inst[2];
  87.     int scan_x = the_hdr->xmin;
  88.     register int was_data;
  89.     short word, long_data, nc, been_some = 0;
  90.  
  91.     /* Add in vertical skip from last scanline */
  92.     if ( the_hdr->priv.get.vert_skip > 0 )
  93.     the_hdr->priv.get.scan_y += the_hdr->priv.get.vert_skip;
  94.  
  95.     /* Set run lengths to 0 */
  96.     for ( channel = (the_hdr->alpha ? -1 : 0);
  97.       channel < the_hdr->ncolors;
  98.       channel++ )
  99.     if ( RLE_BIT( *the_hdr, channel ) )
  100.          nraw[channel] = 0;
  101.     channel = 0;
  102.  
  103.     if ( the_hdr->priv.get.is_eof )
  104.     return 32768;        /* too big for 16 bits, signal EOF */
  105.  
  106.     /* Otherwise, read and interpret instructions until a skipLines
  107.      * instruction is encountered.
  108.      */
  109.     for (was_data = 0;;)
  110.     {
  111.         inst[0] = getc( infile );
  112.     inst[1] = getc( infile );
  113.     if ( feof(infile) )
  114.     {
  115.         the_hdr->priv.get.is_eof = 1;
  116.         break;        /* <--- one of the exits */
  117.     }
  118.  
  119.     switch( OPCODE(inst) )
  120.     {
  121.     case RSkipLinesOp:
  122.         was_data = 1;
  123.         if ( LONGP(inst) )
  124.         {
  125.         VAXSHORT( the_hdr->priv.get.vert_skip, infile );
  126.         }
  127.         else
  128.         the_hdr->priv.get.vert_skip = DATUM(inst);
  129.         break;            /* need to break for() here, too */
  130.  
  131.     case RSetColorOp:
  132.         was_data = 1;
  133.         channel = DATUM(inst);    /* select color channel */
  134.         if ( channel == 255 )
  135.         channel = -1;
  136.         scan_x = the_hdr->xmin;
  137.         if ( RLE_BIT( *the_hdr, channel ) )
  138.         rawp = scanraw[channel];
  139.         else
  140.         rawp = NULL;
  141.         break;
  142.  
  143.     case RSkipPixelsOp:
  144.         was_data = 1;
  145.         if ( LONGP(inst) )
  146.         {
  147.             VAXSHORT( long_data, infile );
  148.         scan_x += long_data;
  149.         }
  150.         else
  151.         {
  152.         scan_x += DATUM(inst);
  153.         }
  154.         break;
  155.  
  156.     case RByteDataOp:
  157.         was_data = 1;
  158.         if ( LONGP(inst) )
  159.         {
  160.             VAXSHORT( nc, infile );
  161.         }
  162.         else
  163.         nc = DATUM(inst);
  164.         nc++;
  165.         if ( rawp != NULL )
  166.         {
  167.         rawp->opcode = RByteDataOp;
  168.         rawp->xloc = scan_x;
  169.         rawp->length = nc;
  170.         rawp->u.pixels = (rle_pixel *)malloc( (unsigned)nc );
  171.         fread( (char *)rawp->u.pixels, 1, nc, infile );
  172.         if ( nc & 1 )
  173.             (void)getc( infile );    /* throw away odd byte */
  174.         rawp++;
  175.         nraw[channel]++;
  176.         }
  177.         else
  178.         if ( the_hdr->priv.get.is_seek )
  179.             fseek( infile, ((nc + 1) / 2) * 2, 1 );
  180.         else
  181.         {
  182.             register int ii;
  183.             for ( ii = ((nc + 1) / 2) * 2; ii > 0; ii-- )
  184.             (void) getc( infile );    /* discard it */
  185.         }
  186.  
  187.         scan_x += nc;
  188.         been_some = 1;
  189.         break;
  190.  
  191.     case RRunDataOp:
  192.         was_data = 1;
  193.         if ( LONGP(inst) )
  194.         {
  195.             VAXSHORT( nc, infile );
  196.         }
  197.         else
  198.         nc = DATUM(inst);
  199.  
  200.         nc++;
  201.         VAXSHORT( word, infile );
  202.         if ( rawp != NULL )
  203.         {
  204.         rawp->opcode = RRunDataOp;
  205.         rawp->xloc = scan_x;
  206.         rawp->length = nc;
  207.         rawp->u.run_val = word;
  208.         rawp++;
  209.         nraw[channel]++;
  210.         }
  211.         scan_x += nc;
  212.         been_some = 1;
  213.         break;
  214.  
  215.     case REOFOp:
  216.         the_hdr->priv.get.is_eof = 1;
  217.         break;
  218.  
  219.     default:
  220.         fprintf( stderr,
  221.              "%s: rle_getraw: Unrecognized opcode: %d, reading %s\n",
  222.              the_hdr->cmd, OPCODE(inst), the_hdr->file_name );
  223.         exit(1);
  224.     }
  225.     if ( OPCODE(inst) == REOFOp )
  226.         break;            /* <--- the other loop exit */
  227.     if ( OPCODE(inst) == RSkipLinesOp )
  228.     {
  229.         if ( been_some )
  230.         break;            /* <--- the other loop exit */
  231.         else
  232.         /* No data on that scanline, so move up to this scanline */
  233.         the_hdr->priv.get.scan_y +=
  234.             the_hdr->priv.get.vert_skip;
  235.     }
  236.     }
  237.  
  238.     /* If at top of image, skip any remaining. */
  239.     if ( the_hdr->priv.get.scan_y >= the_hdr->ymax )
  240.     {
  241.     int y = the_hdr->priv.get.scan_y;
  242.     while ( rle_getskip( the_hdr ) != 32768 )
  243.         ;
  244.     return y;
  245.     }
  246.  
  247.     /* Return current Y value */
  248.     return (was_data == 0) ? 32768 : the_hdr->priv.get.scan_y;
  249. }
  250.  
  251. /*****************************************************************
  252.  * TAG( rle_freeraw )
  253.  * 
  254.  * Free all the pixel arrays in the raw scan struct.
  255.  * Inputs:
  256.  *      the_hdr:    Header struct corresponding to this RLE data.
  257.  *      scanraw:    Array of pointers to array of rle_op, as above.
  258.  *     nraw:        Array of lengths (as above)
  259.  * Outputs:
  260.  *     Frees the areas pointed to by the pixels elements of any
  261.  *      RByteDataOp type rle_op structs.
  262.  * Assumptions:
  263.  *    [None]
  264.  * Algorithm:
  265.  *    [None]
  266.  */
  267. void
  268. rle_freeraw( the_hdr, scanraw, nraw )
  269. rle_hdr * the_hdr;
  270. int nraw[];
  271. rle_op *scanraw[] ;
  272. {
  273.     int c, i;
  274.     register rle_op * raw_p;
  275.  
  276.     for ( c = -the_hdr->alpha; c < the_hdr->ncolors; c++ )
  277.     if ( RLE_BIT( *the_hdr, c ) )
  278.         for ( i = nraw[c], raw_p = scanraw[c]; i > 0; i--, raw_p++ )
  279.         if ( raw_p->opcode == RByteDataOp )
  280.         {
  281.             if ( raw_p->u.pixels )
  282.             free( raw_p->u.pixels );
  283.             else
  284.             fprintf( stderr,
  285.      "%s(%s): rle_freeraw given NULL pixel pointer, %d[%d].\n",
  286.                  the_hdr->cmd, the_hdr->file_name,
  287.                  c, nraw[c] - i );
  288.             raw_p->u.pixels = NULL;
  289.         }
  290. }
  291.